package aspectjutil.eventmanager;

import java.lang.reflect.Method;

import junit.framework.Assert;

import org.junit.Test;


public class EventHandlerTestWithPreEventRecipient extends EventHandlerTestTemplate {
	// Test about @PreEvent method execution by EventProducer.calculate method invocation ---------
	@Test
	public void testPreEventFromCalculateMethod() throws Throwable {
		// Instantiate PreEventRecipient object ---------------------------------------------------
		Object preEventRecipientObj 
		= EventManagerTestUtils.preEventRecipientFactory( childDelegationClassLoader);
		// ----------------------------------------------------------------------------------------
		// Execute EventProducer.calculate method -------------------------------------------------
		Object eventProducerObj = EventManagerTestUtils.eventProducerFactory( childDelegationClassLoader);
		Method calculateMethod 
		= EventManagerTestUtils.getEventProducerCalculateMethod( eventProducerObj.getClass());
		Integer calculationResult = (Integer)calculateMethod.invoke( eventProducerObj, 4, 8);
		// ----------------------------------------------------------------------------------------
		
		// Verifications --------------------------------------------------------------------------
		Assert.assertEquals( 
				EventManagerTestUtils.getEventTraceListDump( eventTraceList) + "\n", 
				2, 
				eventTraceList.size()
				);
			int eventTraceListIndex = -1;
			Assert.assertTrue( 
					EventManagerTestUtils.getEventTraceListDump( eventTraceList),					
					eventTraceList.get( ++eventTraceListIndex)
					.contains( 
							preEventRecipientObj.getClass().getName()
							+ ".staticListenerOfCalculationStart"
							) 
					);
			Assert.assertTrue( 
					EventManagerTestUtils.getEventTraceListDump( eventTraceList),					
					eventTraceList.get( ++eventTraceListIndex)
					.contains( 
							preEventRecipientObj.getClass().getName()
							+ ".onCalculationStart"
							) 
					);
			
			for( int eventTraceIndex = 0; eventTraceIndex < eventTraceList.size(); eventTraceIndex++) {
				Assert.assertEquals( 
						EventManagerTestUtils.getCalculationEventClass( childDelegationClassLoader),
						triggeredEventTraceList.get( eventTraceIndex)
						);
				Class<?> eventerInfoClass 
				= EventManagerTestUtils.getEventerInfoClass( childDelegationClassLoader);
				Object eventerInfo = eventerInfoClass.cast( eventerTraceList.get( eventTraceIndex));
					Assert.assertEquals( 
							eventProducerObj,
							EventManagerTestUtils.getEventerObjOfEventerInfo( eventerInfo)
							);
					Assert.assertEquals( 
							"calculate",
							EventManagerTestUtils.getEventerMethodOfEventerInfo( eventerInfo).getName()
							);
				Assert.assertEquals( 
						null,
						eventResultTraceList.get( eventTraceIndex) 
						);
			} // for
		// ----------------------------------------------------------------------------------------
	} // public void testPreEventFromCalculateMethod() throws Throwable
	// --------------------------------------------------------------------------------------------
	
	// Test about @PreEvent method execution by setting EventProducerByStaticField.price field ----
	@Test
	public void testPreEventFromPriceFieldChange() throws Throwable {
		// Instantiate PreEventRecipient object ---------------------------------------------------
		Object preEventRecipientObj 
		= EventManagerTestUtils.preEventRecipientFactory( childDelegationClassLoader);
		// ----------------------------------------------------------------------------------------
		// Execute EventProducer.setPrice method -------------------------------------------------
		int priceValue = 88;
		EventManagerTestUtils.getSetPriceMethodOfEventProducerByStaticField( childDelegationClassLoader)
		.invoke( null, priceValue);
		// ----------------------------------------------------------------------------------------
		
		// Verifications --------------------------------------------------------------------------
		Assert.assertEquals( 
				EventManagerTestUtils.getEventTraceListDump( eventTraceList) + "\n", 
				2, 
				eventTraceList.size()
				);
			int eventTraceListIndex = -1;
			Assert.assertTrue( 
					EventManagerTestUtils.getEventTraceListDump( eventTraceList),					
					eventTraceList.get( ++eventTraceListIndex)
					.contains( 
							preEventRecipientObj.getClass().getName()
							+ ".staticListenerOfPriceChangeStart"
							) 
					);
			Assert.assertTrue( 
					EventManagerTestUtils.getEventTraceListDump( eventTraceList),					
					eventTraceList.get( ++eventTraceListIndex)
					.contains( 
							preEventRecipientObj.getClass().getName()
							+ ".onPriceChangeStart"
							) 
					);
				
			for( int eventTraceIndex = 0; eventTraceIndex < eventTraceList.size(); eventTraceIndex++) {
				Assert.assertEquals( 
						EventManagerTestUtils.getPriceChangeClass( childDelegationClassLoader),
						triggeredEventTraceList.get( eventTraceIndex) 
						);
				Class<?> eventerInfoClass 
				= EventManagerTestUtils.getEventerInfoClass( childDelegationClassLoader);
				Object eventerInfo = eventerInfoClass.cast( eventerTraceList.get( eventTraceIndex));
					Assert.assertEquals( 
							null, // Because EventProducerByStaticField.price is static field
							EventManagerTestUtils.getEventerObjOfEventerInfo( eventerInfo)
							);
					Assert.assertEquals( 
							"price",
							EventManagerTestUtils.getEventerFieldOfEventerInfo( eventerInfo).getName()
							);
				Assert.assertEquals( 
						priceValue,
						eventResultTraceList.get( eventTraceIndex) 
						);
			} // for
				
		// ----------------------------------------------------------------------------------------
	} // public void testPreEventFromPriceFieldChange()
	// --------------------------------------------------------------------------------------------
}
